package procilege.impl.expand;

import procilege.compute.ExprExpandTraveller;
import procilege.compute.PlaceTypeMetadata;
import procilege.compute.PlaceType;
import procilege.lang.EntityExprAnd;
import procilege.lang.EntityExprElement;
import procilege.lang.EntityExprOr;
import procilege.lang.ExprElement;

@PlaceTypeMetadata(type = EntityExprAnd.class)
public class EntityExprAndExpandPlace implements PlaceType<ExprExpandTraveller> {
	
	@SuppressWarnings("unchecked")
	public void visit(ExprExpandTraveller tr, Object place) {

		EntityExprOr plus = new EntityExprOr();
		plus.add(new EntityExprAnd()); // the identity element.
		
		for (ExprElement t : ((EntityExprAnd) place).getTerms()) {
			tr.setout(t);
			Object r = tr.getPreviousVisitResult();
			if (r == null)
				continue;

			EntityExprOr terms = plus;
			plus = new EntityExprOr();
			if (r instanceof EntityExprOr) {

				for (EntityExprElement rt : (EntityExprOr) r) {
					for (EntityExprElement lt : terms) {
						plus.add(new EntityExprAnd(lt, rt));
					}
				}
			} else if (r instanceof EntityExprElement) {

				for (EntityExprElement lt : terms) {
					plus.add(new EntityExprAnd(lt, (EntityExprElement) r));
				}
			} else
				throw new IllegalStateException("unknown: " + r);
		}

		tr.result(plus);
	}
}